Skip to content

Conversation

@Deydra71
Copy link

Jira: OSPRH-20524

Adds the end-to-end support for consuming Keystone ApplicationCredentials (AC) in the watcher-operator, enabling WatcherAPI, WatcherApplier, and WatcherDecisionEngine pods to use AC-based authentication when available.

Reconcile:

On each reconcile, the Watcher controllers (WatcherAPI, WatcherApplier, WatcherDecisionEngine) check for an AC Secret (ac-watcher-secret) using the GetApplicationCredentialFromSecret() helper from keystone-operator API:

  • If the secret is missing or incomplete, continues using password authentication
  • Once the AC Secret is ready with valid AC_ID and AC_SECRET fields, templates AC credentials into the shared service configuration (00-default.conf)
  • The configuration hash naturally includes AC values, triggering rolling updates when credentials rotate
  • All three child controllers use the same 'watcher' user and shared AC Secret

Both [keystone_authtoken] and [watcher_clients_auth] sections in 00-default.conf are updated to support AC authentication with a block-based if-else structure.

Secret Watchers:

Each child controller (WatcherAPI, WatcherApplier, WatcherDecisionEngine) watches the AC Secret (ac-watcher-secret) to trigger reconciliation when the secret is created, updated, or deleted.

Depends-On: openstack-k8s-operators/keystone-operator#567

Adds the end-to-end support for consuming Keystone ApplicationCredentials (AC) in the watcher-operator, enabling WatcherAPI, WatcherApplier, and WatcherDecisionEngine pods to use AC-based authentication when available.

Signed-off-by: Veronika Fisarova <vfisarov@redhat.com>
@openshift-ci openshift-ci bot requested review from cescgina and dprince December 15, 2025 14:24
@openshift-ci
Copy link

openshift-ci bot commented Dec 15, 2025

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign seanmooney for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Copy link
Collaborator

@SeanMooney SeanMooney left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i have not looked at he functional test but the current changes are no following the patter we use in the watcher operator.

we shoudl also have kuttl test ideally for this.
in would also like to see one of the tempest jobs use this pattern but that could be in a separate PR

}

// Check for Application Credentials
templateParameters["UseApplicationCredentials"] = false
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we normally do not use booleans for this
we isntead follow the pattern of chekcign if the parmares are empty in the template.

https://github.com/openstack-k8s-operators/watcher-operator/blob/main/templates/00-default.conf#L8-L10

can you refactor this to use that pattern

in this case you shoudl generate the approate section if

"ACID" is populated

{{ if (index . "ACID") }}
...
{{ end}}


// Check for Application Credentials
templateParameters["UseApplicationCredentials"] = false
if acData, err := keystonev1.GetApplicationCredentialFromSecret(ctx, r.Client, instance.Namespace, watcher.ServiceName); err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok so keystone is going to provide a helper function it its api module instead of each fo the service operators using ensureSecret

this is not quite correct for watcher nova or placement because we create separate secrets for sub cr each so the top level watcher controller shoudl receive the application credential and look up the info form the keystone created secret and then populate that into the per CR secrete

so we should look this up once here

https://github.com/openstack-k8s-operators/watcher-operator/blob/main/internal/controller/watcher_controller.go#L285-L353

then extend createSubLevelSecret to propagate the application credential info into the service secrets.

https://github.com/openstack-k8s-operators/watcher-operator/blob/main/internal/controller/watcher_controller.go#L355-L360
https://github.com/openstack-k8s-operators/watcher-operator/blob/main/internal/controller/watcher_controller.go#L862

even if we were to ignore that pattenr which i dont think we should we would add a new fucntion to the base reconsolie instead to aovid repeating this per service contoler.

https://github.com/openstack-k8s-operators/watcher-operator/blob/main/internal/controller/watcher_common.go#L407-L448

},
})
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks incorrect to me.

we watcher secrets or other CRDs

genericly

https://github.com/openstack-k8s-operators/watcher-operator/blob/main/internal/controller/watcherapi_controller.go#L938-L952

the looping over the relevant objects and creation of reconsile request is don by

https://github.com/openstack-k8s-operators/watcher-operator/blob/main/internal/controller/watcherapi_controller.go#L956-L1019

so you shoudl not be generating the reconsile reqeust hree

you would follw the same patthern as the passwordSecretFiled and return a slice of strings []string

// index passwordSecretField
if err := mgr.GetFieldIndexer().IndexField(context.Background(), &watcherv1beta1.WatcherAPI{}, passwordSecretField, func(rawObj client.Object) []string {
	// Extract the secret name from the spec, if one is provided
	cr := rawObj.(*watcherv1beta1.WatcherAPI)
	if cr.Spec.Secret == "" {
		return nil
	}
	return []string{cr.Spec.Secret}
}); err != nil {
	return err
}

with that said as i indicated above the applcition credtial shoudl be manged at the toplevel contoler and the API/applier/descison engine should jus twhatc there input secret.

basiclly the top level contoler will watch the appcliatce credtial secret/CRD and update the subCR secrete, the subcr contoler like the water api contole only watch there secret not teh applcation credital one.

@SeanMooney
Copy link
Collaborator

SeanMooney commented Dec 15, 2025

the current design regresses #30 by making each controller depend on the the application credential directly.
https://issues.redhat.com//browse/OSPRH-11483

@softwarefactory-project-zuul
Copy link

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/980f61d6994b45f090a0c385ce6ea6af

openstack-meta-content-provider-master FAILURE in 35m 06s
⚠️ watcher-operator-validation-master SKIPPED Skipped due to failed job openstack-meta-content-provider-master
✔️ openstack-meta-content-provider-epoxy SUCCESS in 2h 37m 29s
✔️ watcher-operator-validation-epoxy SUCCESS in 2h 05m 50s
watcher-operator-validation-epoxy-ocp4-16 FAILURE in 23m 59s
✔️ noop SUCCESS in 0s
⚠️ watcher-operator-kuttl SKIPPED Skipped due to failed job openstack-meta-content-provider-master

@Deydra71
Copy link
Author

Hey @SeanMooney ! Thanks for the review. We decided today that we will refactor the app cred support in service operators to create a new CRD field for appCredSecret name. So, we will get rid of the watchers, and will use field index instead in only parent controller, as you suggested.

I will prepare changes soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants